package com.pengpai.pangucms.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pengpai.pangucms.VO.CategoryVO;
import com.pengpai.pangucms.entity.SysFileinfo;
import com.pengpai.pangucms.entity.WebArticle;
import com.pengpai.pangucms.entity.WebCategory;
import com.pengpai.pangucms.service.ISysFileinfoService;
import com.pengpai.pangucms.service.IWebArticleService;
import com.pengpai.pangucms.service.IWebCategoryService;
import com.pengpai.pangucms.utils.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wushuai
 * @since 2023-08-29
 */
@Controller
@RequestMapping("/webArticle")
public class WebArticleController {

    @Resource
    private IWebArticleService webArticleService;

    @Resource
    private IWebCategoryService webCategoryService;

    @Resource
    private TemplateEngine templateEngine;

    @Resource
    private ISysFileinfoService sysFileinfoService;

    @Value("${pangu.upload.root}")
    private String root;

    @GetMapping("/index")
    @PreAuthorize("hasAuthority('web:article:read')")
    public String index(){
        return "admin/web_article/web_article_index";
    }

    @GetMapping("/tree")
    @ResponseBody
    @PreAuthorize("hasAuthority('web:article:read')")
    public ResultTree tree() {
        List<WebCategory> list = webCategoryService.list();
        ResultTree resultTree = new ResultTree();
        List<CategoryVO> webCategoryList = new ArrayList<>();

        for (WebCategory wc : list) {
            if(wc.getIsDel() == 1) continue;
            CategoryVO categoryVO = new CategoryVO();
            categoryVO.setId(wc.getCategoryId());
            categoryVO.setTitle(wc.getCategoryName());
            categoryVO.setParentId(wc.getParentId());
            webCategoryList.add(categoryVO);
        }
        webCategoryList.add(new CategoryVO(0, -1, "顶级栏目"));
        List<CategoryVO> tree = TreeUtil.webCategoryVoToTree(webCategoryList, -1);
        resultTree.setData(tree);

        return resultTree;
    }

    @GetMapping("list")
    @ResponseBody
    @PreAuthorize("hasAuthority('web:article:read')")
    public ResultTable list(WebArticle webArticle, int page, int limit){
        Page<WebArticle> webArticlePage = new Page<>(page,limit);
        QueryWrapper<WebArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(webArticle.getArticleName()), "article_name", webArticle.getArticleName())
                .or().like(StrUtil.isNotBlank(webArticle.getCreateUser()), "create_user", webArticle.getCreateUser())
                .or().like(StrUtil.isNotBlank(webArticle.getCategoryName()), "category_name", webArticle.getCategoryName())
                .or().eq(webArticle.getCategoryId()!=null, "category_id", webArticle.getCategoryId())
                .orderByAsc("sort").orderByDesc("update_time");
        List<WebArticle> webArticleList = webArticleService.page(webArticlePage, queryWrapper).getRecords();
        return ResultTable.pageTable(webArticlePage.getTotal(), webArticleList);
    }

    @GetMapping("add")
    @PreAuthorize("hasAuthority('web:article:create')")
    public String add(){
        return "admin/web_article/web_article_add";
    }

    @PostMapping("create")
    @ResponseBody
    @PreAuthorize("hasAuthority('web:article:create')")
    public R create(WebArticle webArticle){
        webArticle.setCreateUser(UserUtils.CurrentUserName());
        webArticle.setCreateTime(LocalDateTime.now());
        webArticle.setUpdateTime(LocalDateTime.now());
        webArticle.setUpdateUser(UserUtils.CurrentUserName());
        WebCategory category = webCategoryService.getById(webArticle.getCategoryId());
        if(category!= null) webArticle.setCategoryName(category.getCategoryName());
        if(webArticle.getFileCodes()!= null && !"".equals(webArticle.getFileCodes())){
            String fileNames = "";
            String[] split = webArticle.getFileCodes().split(",");
            for (String code : split) {
                QueryWrapper<SysFileinfo> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("file_code", code);
                fileNames = fileNames + sysFileinfoService.getOne(queryWrapper).getFileName() + ",";
            }
            webArticle.setFileNames(fileNames);
        }
        webArticleService.save(webArticle);
        return R.success();
    }

    @PostMapping("/del")
    @ResponseBody
    @PreAuthorize("hasAuthority('web:article:delete')")
    public R del(String ids){
        List<Long> list = null;
        if(StrUtil.isNotBlank(ids)){
            list = Stream.of(ids.split(",")).map(Long::parseLong).collect(Collectors.toList());
        }
        webArticleService.removeByIds(list);
        return R.success();
    }

    @PostMapping("update")
    @ResponseBody
    @PreAuthorize("hasAuthority('web:article:update')")
    public R update(WebArticle webArticle){
        WebArticle original = webArticleService.getById(webArticle.getArticleId());
        if(original.getCategoryId() != null && webArticle.getCategoryId() != null && original.getCategoryId() != webArticle.getCategoryId()){
            WebCategory category = webCategoryService.getById(webArticle.getCategoryId());
            webArticle.setCategoryName(category.getCategoryName());
        }
        webArticle.setUpdateTime(LocalDateTime.now());
        webArticle.setUpdateUser(UserUtils.CurrentUserName());
        WebCategory category = webCategoryService.getById(webArticle.getCategoryId());
        if(category != null) {
            webArticle.setCategoryName(category.getCategoryName());
        }else {
            webArticle.setCategoryName(null);
        }
        if(webArticle.getFileCodes()!= null && !"".equals(webArticle.getFileCodes())){
            String fileNames = "";
            String[] split = webArticle.getFileCodes().split(",");
            for (String code : split) {
                QueryWrapper<SysFileinfo> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("file_code", code);
                fileNames = fileNames + sysFileinfoService.getOne(queryWrapper).getFileName() + ",";
            }
            webArticle.setFileNames(fileNames);
        }
        webArticleService.updateById(webArticle);
        return R.success("栏目信息更新成功！");
    }

    @GetMapping("/edit")
    @PreAuthorize("hasAuthority('web:article:update')")
    public String edit(String id, Model model){
        WebArticle webArticle = webArticleService.getById(id);
        // 根据fileCode解析图片相对路径
        String uuidName = webArticle.getCoverImage();
        QueryWrapper<SysFileinfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("file_code", uuidName);
        SysFileinfo fileinfo = sysFileinfoService.getOne(queryWrapper);
        String imgPath = "";
        if(uuidName != null && fileinfo != null){
            imgPath = "/files/" + uuidName + fileinfo.getFileSuff();
//            webArticle.setCoverImage(filePath);
        }
        if(webArticle.getFileCodes()!=null && !"".equals(webArticle.getFileCodes())){
            String[] split = webArticle.getFileCodes().split(",");
            List<SysFileinfo> list = new ArrayList<>();
            for (String code : split) {
                QueryWrapper<SysFileinfo> qWrapper = new QueryWrapper<>();
                qWrapper.eq("file_code", code);
                SysFileinfo file = sysFileinfoService.getOne(qWrapper);
                double size = Double.parseDouble(file.getFileSize().toString());
                size = size / 1024;
                file.setFileSize(String.format("%.1f", size) + "kb");
                list.add(file);
            }
            model.addAttribute("fls", list);
        }
        model.addAttribute("imgPath", imgPath);
        model.addAttribute("wa", webArticle);
        return "admin/web_article/web_article_edit";
    }

    @GetMapping("/preview")
    @PreAuthorize("hasAuthority('web:article:update')")
    public String preview(String id, Model model){
        WebArticle webArticle = webArticleService.getById(id);
        String htmlContent = webArticle.getHtmlContent();
        htmlContent = StringEscapeUtils.unescapeHtml4(htmlContent);
        webArticle.setHtmlContent(htmlContent);
        List<WebCategory> list = webCategoryService.list();
        List<CategoryVO> webCategoryList = new ArrayList<>();
        for (WebCategory wc : list) {
            if(wc.getIsDel() == 1) continue;
            CategoryVO categoryVO = new CategoryVO();
            categoryVO.setId(wc.getCategoryId());
            categoryVO.setTitle(wc.getCategoryName());
            categoryVO.setParentId(wc.getParentId());
            categoryVO.setVisitUrl(wc.getVisitUrl());
            webCategoryList.add(categoryVO);
        }
        List<CategoryVO> acList = TreeUtil.webCategoryVoToTree(webCategoryList, 0);
        // 附件
        List<SysFileinfo> fileList = null;
        if(webArticle.getFileCodes()!=null && !"".equals(webArticle.getFileCodes())){
            fileList = new ArrayList<>();
            String fileIds = webArticle.getFileCodes();
            String[] fids = fileIds.split(",");
            for (String fid : fids) {
                QueryWrapper<SysFileinfo> qWrapper = new QueryWrapper<>();
                qWrapper.eq("file_code", fid);
                SysFileinfo file = sysFileinfoService.getOne(qWrapper);
                fileList.add(file);
            }
        }
        if(fileList != null) model.addAttribute("fileList", fileList);
        model.addAttribute("wcl", acList);
        model.addAttribute("wa", webArticle);
        return "website/article_tmp";
    }

    @PostMapping("/staticPage")
    @PreAuthorize("hasAuthority('web:article:update')")
    @ResponseBody
    public R staticPage(String id, HttpServletResponse response, HttpServletRequest request){
        WebArticle webArticle = webArticleService.getById(id);
        String htmlContent = webArticle.getHtmlContent();
        htmlContent = StringEscapeUtils.unescapeHtml4(htmlContent);
        webArticle.setHtmlContent(htmlContent);
        List<WebCategory> list = webCategoryService.list();
        List<CategoryVO> webCategoryList = new ArrayList<>();
        for (WebCategory wc : list) {
            if(wc.getIsDel() == 1) continue;
            CategoryVO categoryVO = new CategoryVO();
            categoryVO.setId(wc.getCategoryId());
            categoryVO.setTitle(wc.getCategoryName());
            categoryVO.setParentId(wc.getParentId());
            categoryVO.setVisitUrl(wc.getVisitUrl());
            webCategoryList.add(categoryVO);
        }
        List<CategoryVO> acList = TreeUtil.webCategoryVoToTree(webCategoryList, 0);
        List<SysFileinfo> fileList = null;
        // 附件
        if(webArticle.getFileCodes()!=null && !"".equals(webArticle.getFileCodes())){
            fileList = new ArrayList<>();
            String fileIds = webArticle.getFileCodes();
            String[] fids = fileIds.split(",");
            for (String fid : fids) {
                QueryWrapper<SysFileinfo> qWrapper = new QueryWrapper<>();
                qWrapper.eq("file_code", fid);
                SysFileinfo file = sysFileinfoService.getOne(qWrapper);
                fileList.add(file);
            }
        }
        Context context = new Context();
        if(fileList != null) context.setVariable("fileList", fileList);
        context.setVariable("wa", webArticle);
        context.setVariable("wcl", acList);
        PrintWriter printWriter = null;
        try {
            //把静态文件生成到服务器本地
//            Integer categoryId = webArticle.getCategoryId();
//            WebCategory category = webCategoryService.getById(categoryId);
//            root = root + "/"+category.getVisitUrl();
            File f = new File(root+ "/pages");
            if(!f.exists()){
                f.mkdirs();
            }
            File file = new File(root + "/pages/" + id + ".html");
            printWriter = new PrintWriter(file);
            templateEngine.process("website/article_tmp", context, printWriter);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return R.fail("静态化页面制作失败！");
        } finally {
            if (printWriter != null) {
                printWriter.close();
            }
        }
        webArticleService.updateById(webArticle);
        return R.success("静态化页面制作成功！");
    }

    @PostMapping("/publish")
    @PreAuthorize("hasAuthority('web:article:update')")
    @ResponseBody
    public R publish(String articleId){
        WebArticle webArticle = webArticleService.getById(articleId);
        webArticle.setIsShow(1);
        webArticleService.updateById(webArticle);
        return R.success("文章发布成功！");
    }

    @PostMapping("/unpublish")
    @PreAuthorize("hasAuthority('web:article:update')")
    @ResponseBody
    public R unpublish(String articleId){
        WebArticle webArticle = webArticleService.getById(articleId);
        webArticle.setIsShow(0);
        webArticleService.updateById(webArticle);
        return R.success("文章取消发布成功！");
    }

}
